﻿#region

using System.Linq;
using System.Data.Entity;
using xConnected.Core.Common.Paging;
using xConnected.Core.Interfaces.Data;
using xConnected.Core.Interfaces.Paging;
using xConnected.Core.Model;
using xConnected.Core.Model.ViewModel.xConnected.Core.Model.ViewModel;

#endregion

namespace xConnected.Data
{
    public partial class PositionRepository : BaseRepository<Position>, IPositionRepository
    {

        public override Position GetById(int id)
        {
            return DbSet
                .Include(p => p.CompanyProfile.User)
                .Include(p => p.CompanyProfile.User.ExpertProfiles)
                .Include(p => p.CompanyProfile.User.CompanyProfiles)
                .Include(p => p.CompanyProfile.User.CompanyProfiles.Select(c => c.Positions))
                .Include(p => p.Categories)
                .Include(p => p.Technologies)
                .Include(p => p.Country)
                .Include(p => p.Industry).SingleOrDefault(p => p.Id == id);
        }

        public override IQueryable<Position> GetAll()
        {
            return DbSet
                .Include(p => p.CompanyProfile)
                .Include(p => p.CompanyProfile.User)
                .Include(p => p.Country)
                .Include(p => p.Industry)
                .Include(p => p.Categories)
                .Include(p => p.Technologies);
        }
        //PAGING

        #region IPositionRepository Members

        public IPage<Position> AdvancedPagedSearchedAll(AdvancedSearchModelPosition position)
        {
            var data = AdvancedSearchAll(position);
            //if method is called from MyProfiles mode and if ShowAll is selected return all profiles
            //if ShowAll is not selected return only first 3 profiles
            position.PageSize = position.UserId != 0
                                       ? position.ShowAll ? data.Count() : 3
                                       : position.PageSize;
            var pagedData =
                data.OrderBy(k => k.Id).Skip(position.PageSize*position.PageIndex).Take(position.PageSize).AsEnumerable();
            return new Page<Position>(pagedData, data.Count(), position.PageSize, position.PageIndex);
        }

        public IPage<Position> AdvancedPagedSearchedSome(AdvancedSearchModelPosition position)
        {
            var data = AdvancedSearchSome(position);
            var pagedData =
                data.OrderBy(k => k.Id).Skip(position.PageSize*position.PageIndex).Take(position.PageSize).AsEnumerable();
            return new Page<Position>(pagedData, data.Count(), position.PageSize, position.PageIndex);
        }

        public override void Delete(Position entity)
        {
            DbSet.Remove(DbSet.Single(c => c.Id == entity.Id));
        }

        #endregion

        private IQueryable<Position> AdvancedSearchAll(AdvancedSearchModelPosition positionModel)
        {
            IQueryable<Position> Positions = positionModel.UserId == 0
                                               ? DbSet
                                               : DbSet.Where(p => p.CompanyProfile.User.Id == positionModel.UserId);

            if (positionModel.Keywords != null && positionModel.Keywords.Count != 0)
            {
                //if (positionModel.SimpleSearch)
                //{
                //    Positions =
                //        Positions.Where(
                //            p =>
                //            p.Title.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Description.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Location.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Duration.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Categories.Any(c => c.Description.ToLower().Contains(positionModel.Keywords.ToLower())) ||
                //            p.Technologies.Any(t => t.Name.ToLower().Contains(positionModel.Keywords.ToLower())) ||
                //            p.CompanyProfile.Industry.Description.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Country.Description.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.CompanyProfile.Title.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.CompanyProfile.Description.ToLower().Contains(positionModel.Keywords.ToLower()));
                //}
                //else
                //{
                Positions =
                    Positions.Where(
                        p => positionModel.Keywords.Any(k => k.ToLower().Contains(p.Description.ToLower())) ||
                             positionModel.Keywords.Any(k => k.ToLower().Contains(p.Duration.ToLower())));
                // }
            }
            if (!string.IsNullOrEmpty(positionModel.Title))
            {
                if (positionModel.Title.Contains(" "))
                {
                    string[] TitleSplit = positionModel.Title.Split(' ');
                    Positions = Positions.Where(p => TitleSplit.Any(t => t.ToLower().Contains(p.Title.ToLower())) || p.Title.ToLower().Contains(positionModel.Title.ToLower()));
                }
                else
                {
                    Positions = Positions.Where(p => p.Title.ToLower().Contains(positionModel.Title.ToLower()));
                }
            }
            if (!string.IsNullOrEmpty(positionModel.Location))
            {
                Positions = Positions.Where(p => p.Location.ToLower().Contains(positionModel.Location.ToLower()));
            }
            if (!string.IsNullOrEmpty(positionModel.Duration))
            {
                Positions = Positions.Where(p => p.Duration.ToLower().Contains(positionModel.Duration.ToLower()));
            }
            if (positionModel.JobType.HasValue)
            {
                if (positionModel.JobType != -1)
                {
                    Positions = Positions.Where(p => p.JobType == positionModel.JobType.Value);
                }
            }
            if (positionModel.CountryIds != null && positionModel.CountryIds.Count != 0)
            {
                if (positionModel.CountryIds[0] != -1)
                {
                    Positions = positionModel.CountryIds[0] != -1
                                   ? Positions.Where(p => positionModel.CountryIds.Contains(p.CountryId))
                                   : Positions;
                }
            }
            if (positionModel.IndustryIds != null && positionModel.IndustryIds.Count != 0)
            {
                Positions = positionModel.IndustryIds[0] != -1
                               ? Positions.Where(p => positionModel.IndustryIds.Contains(p.Industry.Id))
                               : Positions;
            }
            if (positionModel.CategoryIds != null && positionModel.CategoryIds.Count != 0)
            {
                Positions =
                    Positions.Where(p => p.Categories.Select(c => c.Id).Any(id => positionModel.CategoryIds.Contains(id)));
            }
            if (positionModel.TechnologyIds != null && positionModel.TechnologyIds.Count != 0)
            {
                Positions =
                    Positions.Where(
                        p => p.Technologies.Select(c => c.Id).Any(id => positionModel.TechnologyIds.Contains(id)));
            }
            if (positionModel.CompanyProfileIds != null && positionModel.CompanyProfileIds.Count != 0)
            {
                Positions = Positions.Where(p => positionModel.CompanyProfileIds.Contains(p.CompanyProfileId));
            }
            return Positions.Include(p => p.Country)
                            .Include(p => p.CompanyProfile)
                            .Include(p => p.Industry)
                            .Include(p => p.Categories)
                            .Include(p => p.Technologies)
                            .AsNoTracking(); 
        }

        private IQueryable<Position> AdvancedSearchSome(AdvancedSearchModelPosition positionModel)
        {
            IQueryable<Position> Positions = GetAll();
            var PositionsList = Positions.Where(p => p.Id == 0);
            IQueryable<Position> PositionsKeywords;
            IQueryable<Position> PositionsTitle;
            IQueryable<Position> PositionsLocation;
            IQueryable<Position> PositionsDuration;
            IQueryable<Position> PositionsContractType;
            IQueryable<Position> PositionsCountries;
            IQueryable<Position> PositionsIndustries;
            IQueryable<Position> PositionsCategories;
            IQueryable<Position> PositionsTechnologies;
            IQueryable<Position> PositionsCompanies;

            if (positionModel.Keywords != null)
            {
                //if (positionModel.SimpleSearch)
                //{
                //    PositionsKeywords =
                //        Positions.Where(
                //            p =>
                //            p.Title.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Description.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Location.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Duration.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Categories.Any(c => c.Description.ToLower().Contains(positionModel.Keywords.ToLower())) ||
                //            p.Technologies.Any(t => t.Name.ToLower().Contains(positionModel.Keywords.ToLower())) ||
                //            p.CompanyProfile.Industry.Description.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.Country.Description.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.CompanyProfile.Title.ToLower().Contains(positionModel.Keywords.ToLower()) ||
                //            p.CompanyProfile.Description.ToLower().Contains(positionModel.Keywords.ToLower()));
                //}
                //else
                //{
                PositionsKeywords =
                    Positions.Where(
                        p => positionModel.Keywords.Any(k => k.ToLower().Contains(p.Description.ToLower())) ||
                             positionModel.Keywords.Any(k => k.ToLower().Contains(p.Duration.ToLower())));
                //}
                PositionsList = PositionsList.Union(PositionsKeywords);
            }
            if (positionModel.Title != null)
            {
                if (positionModel.Title.Contains(" "))
                {
                    string[] TitleSplit = positionModel.Title.Split(' ');
                    PositionsTitle = Positions.Where(p => TitleSplit.Any(t => t.ToLower().Contains(p.Title.ToLower())) || p.Title.ToLower().Contains(positionModel.Title.ToLower()));
                }
                else
                {
                    PositionsTitle = Positions.Where(p => p.Title.ToLower().Contains(positionModel.Title.ToLower()));
                }
                PositionsList = PositionsList.Union(PositionsTitle);
            }
            if (positionModel.Location != null)
            {
                PositionsLocation =
                    Positions.Where(p => p.Location.ToLower().Contains(positionModel.Location.ToLower()));
                PositionsList = PositionsList.Union(PositionsLocation);
            }
            if (positionModel.Duration != null)
            {
                PositionsDuration =
                    Positions.Where(p => p.Duration == positionModel.Duration);
                PositionsList = PositionsList.Union(PositionsDuration);
            }
            if (positionModel.JobType.HasValue)
            {
                if (positionModel.JobType != -1)
                {
                    PositionsContractType = Positions.Where(p => p.JobType == positionModel.JobType.Value);
                    PositionsList = PositionsList.Union(PositionsContractType);
                }
            }
            if (positionModel.CountryIds != null)
            {
                if (positionModel.CountryIds[0] != -1)
                {
                    PositionsCountries = Positions.Where(p => positionModel.CountryIds.Contains(p.CountryId));
                    PositionsList = PositionsList.Union(PositionsCountries);
                }
            }
            if (positionModel.IndustryIds != null)
            {
                if (positionModel.IndustryIds[0] != -1)
                {
                    PositionsIndustries = Positions.Where(p => positionModel.IndustryIds.Contains(p.Industry.Id));
                    PositionsList = PositionsList.Union(PositionsIndustries);
                }
            }
            if (positionModel.CategoryIds != null)
            {
                PositionsCategories =
                    Positions.Where(
                        p => p.Categories.Select(c => c.Id).Any(id => positionModel.CategoryIds.Contains(id)));
                PositionsList = PositionsList.Union(PositionsCategories);
            }
            if (positionModel.TechnologyIds != null)
            {
                PositionsTechnologies =
                    Positions.Where(
                        p => p.Technologies.Select(c => c.Id).Any(id => positionModel.TechnologyIds.Contains(id)));
                PositionsList = PositionsList.Union(PositionsTechnologies);
            }
            if (positionModel.CompanyProfileIds != null)
            {
                PositionsCompanies = Positions.Where(p => positionModel.CompanyProfileIds.Contains(p.CompanyProfileId));
                PositionsList = PositionsList.Union(PositionsCompanies);
            }

            return PositionsList;
        }
    }
}